package com.training.web.controller;

import com.training.base.Result;
import com.google.gson.Gson;
import com.training.base.ResponseUtils;
import com.training.bean.Audio;
import com.training.bean.CourseContent;
import com.training.utils.AESUtil;
import com.training.utils.FileUploadUtil;
import com.training.utils.UrlUtils;
import com.training.web.service.WebAudioService;
import com.training.web.service.WebCourseService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.crypto.SecretKey;

@RestController
@RequestMapping("/api/web/audio")
public class WebAudioController {
    @Autowired
    private WebAudioService service;
    
    @Autowired
    private WebCourseService courseService;
    
    @Autowired
    private FileUploadUtil fileUploadUtil;
    
    @Autowired
    private Gson gson;
    
    @Autowired
    private ResponseUtils responseUtils;
    
    @Value("${upload.path}")
    private String uploadPath;
    
    // 从配置文件中获取音频加密密钥
    @Value("${audio.encryption.key}")
    private String audioEncryptionKey;
    
    /**
     * 获取指定课程内容的所有音频（后台管理专用）
     * @param ccid 课程内容ID
     * @return 音频列表结果
     */
    @GetMapping("/getAllAudios")
    public ResponseEntity<Result<List<Audio>>> getAllAudios(@RequestParam int ccid, HttpServletRequest request) {
        try {
            List<Audio> allAudios = service.getAllAudios(ccid);
            // 为每个音频动态构建完整URL
            List<Audio> audiosWithFullUrls = allAudios.stream()
                .map(audio -> {
                    if (audio.getAudio_url() != null && !audio.getAudio_url().isEmpty()) {
                        audio.setAudio_url(UrlUtils.buildFullUrl(request, audio.getAudio_url()));
                    }
                    return audio;
                })
                .collect(Collectors.toList());
            return responseUtils.success(audiosWithFullUrls, "获取音频列表成功");
        } catch (Exception e) {
            e.printStackTrace();
            return responseUtils.failWithType(500, "获取音频失败: " + e.getMessage());
        }
    }
    
    /**
     * 添加音频（后台管理专用）
     * @param ccid 课程内容ID
     * @param name 音频名称
     * @param audioFile 音频文件
     * @param request HTTP请求对象
     * @return 添加结果
     */
    @PostMapping("/addAudio")
    public ResponseEntity<Result<Audio>> addAudio(
            @RequestParam("ccid") int ccid,
            @RequestParam("name") String name,
            @RequestParam("duration") long duration,
            @RequestParam(value = "audioFile", required = false) MultipartFile audioFile,
            HttpServletRequest request) {
        try {
            // 获取课程内容标题和相关信息
            String contentTitle = "unknown";
            String courseTitle = "unknown";
            String stageTitle = "unknown";
            
            CourseContent content = courseService.findContent(ccid).orElse(null);
            if (content != null) {
                contentTitle = content.getTitle();
                // 获取课程信息
                Optional<com.training.bean.Course> courseOpt = courseService.findCourse(content.getCid());
                if (courseOpt.isPresent()) {
                    com.training.bean.Course course = courseOpt.get();
                    courseTitle = course.getTitle();
                    // 获取课程阶段信息
                    int csid = course.getCsid();
                    stageTitle = courseService.getStageTitleById(csid);
                }
            }
            
            // 创建音频对象
            Audio audio = new Audio();
            audio.setCcid(ccid);
            audio.setName(name);
            audio.setDuration(duration);

            // 处理上传的音频文件
            String fileUrl = null;
            if (audioFile != null && !audioFile.isEmpty()) {
                String path = "course_stage/" + fileUploadUtil.sanitizePath(stageTitle) + 
                             "/course/" + fileUploadUtil.sanitizePath(courseTitle) + 
                             "/course_content/" + fileUploadUtil.sanitizePath(contentTitle) + 
                             "/audio";
                
                // 生成加密密钥并加密音频文件
                SecretKey secretKey = AESUtil.loadKey(audioEncryptionKey);
                fileUrl = fileUploadUtil.uploadAndEncryptAudioFileToSubdirectory(audioFile, path, secretKey);
            }
            if (fileUrl != null) {
                audio.setAudio_url(fileUrl);
            }
            
            // 设置创建和更新时间
            Date now = new Date();
            audio.setCreate_date(now);
            audio.setUpdata_date(now);
            
            // 保存音频
            Audio savedAudio = service.addAudio(audio);
            return responseUtils.success(savedAudio, "添加音频成功");
        } catch (Exception e) {
            e.printStackTrace();
            return responseUtils.failWithType(500, "添加音频失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新音频信息（后台管理专用）
     * @param id 音频ID
     * @param ccid 课程内容ID
     * @param name 音频名称
     * @param audioFile 音频文件
     * @param request HTTP请求对象
     * @return 更新结果
     */
    @PostMapping("/updateAudio")
    public ResponseEntity<Result<Audio>> updateAudio(
            @RequestParam("id") int id,
            @RequestParam("ccid") int ccid,
            @RequestParam("name") String name,
            @RequestParam("duration") long duration,
            @RequestParam(value = "audioFile", required = false) MultipartFile audioFile,
            HttpServletRequest request) {
        try {
            // 查找现有音频
            Audio existingAudio = service.getAudioById(id);
            if (existingAudio == null) {
                return (ResponseEntity<Result<Audio>>) (Object) responseUtils.fail(500, "音频不存在，ID: " + id);
            }
            
            // 保存旧音频URL，以便在更新后删除
            String oldAudioUrl = existingAudio.getAudio_url();
            
            // 获取课程内容标题和相关信息
            String contentTitle = "unknown";
            String courseTitle = "unknown";
            String stageTitle = "unknown";
            
            CourseContent content = courseService.findContent(ccid).orElse(null);
            if (content != null) {
                contentTitle = content.getTitle();
                // 获取课程信息
                Optional<com.training.bean.Course> courseOpt = courseService.findCourse(content.getCid());
                if (courseOpt.isPresent()) {
                    com.training.bean.Course course = courseOpt.get();
                    courseTitle = course.getTitle();
                    // 获取课程阶段信息
                    int csid = course.getCsid();
                    stageTitle = courseService.getStageTitleById(csid);
                }
            }
            
            // 更新音频信息
            existingAudio.setCcid(ccid);
            existingAudio.setName(name);
            existingAudio.setDuration(duration);

            // 处理上传的新音频文件
            String fileUrl = null;
            if (audioFile != null && !audioFile.isEmpty()) {
                String path = "course_stage/" + fileUploadUtil.sanitizePath(stageTitle) + 
                             "/course/" + fileUploadUtil.sanitizePath(courseTitle) + 
                             "/course_content/" + fileUploadUtil.sanitizePath(contentTitle) + 
                             "/audio";
                
                // 生成加密密钥并加密音频文件
                SecretKey secretKey = AESUtil.loadKey(audioEncryptionKey);
                fileUrl = fileUploadUtil.uploadAndEncryptAudioFileToSubdirectory(audioFile, path, secretKey);
                
                if (fileUrl != null) {
                    existingAudio.setAudio_url(fileUrl);
                }
            }
            
            // 设置更新时间
            existingAudio.setUpdata_date(new Date());
            
            // 保存更新后的音频
            Audio updatedAudio = service.updateAudio(existingAudio);
            
            // 如果上传了新音频且旧音频存在，则删除旧音频文件
            if (fileUrl != null && oldAudioUrl != null && !oldAudioUrl.isEmpty() && !oldAudioUrl.equals(fileUrl)) {
                fileUploadUtil.deleteFile(oldAudioUrl);
            }
            
            return responseUtils.success(updatedAudio, "更新音频成功");
        } catch (Exception e) {
            e.printStackTrace();
            return (ResponseEntity<Result<Audio>>) (Object) responseUtils.fail(500, "更新音频失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除音频（后台管理专用）
     * @param id 音频ID
     * @return 删除结果
     */
    @DeleteMapping("/deleteAudio/{id}")
    public ResponseEntity<Result<Object>> deleteAudio(@PathVariable int id) {
        try {
            // 先获取要删除的音频对象以获取文件路径
            Audio audio = service.getAudioById(id);
            if (audio != null) {
                // 删除音频文件
                String audioUrl = audio.getAudio_url();
                if (audioUrl != null && !audioUrl.isEmpty()) {
                    fileUploadUtil.deleteFile(audioUrl);
                }
            }
            
            // 从数据库中删除音频记录
            service.deleteAudio(id);
            return responseUtils.success(null, "删除音频成功");
        } catch (Exception e) {
            e.printStackTrace();
            return responseUtils.fail(500, "删除音频失败: " + e.getMessage());
        }
    }
    
    /**
     * 解密并播放音频（后台管理专用）
     * @param filePath 音频文件路径
     * @param response HTTP响应对象
     * @param request HTTP请求对象
     */
    @GetMapping("/playAudio")
    public void playAudio(@RequestParam("filePath") String filePath, HttpServletResponse response, HttpServletRequest request) {
        try {
            // 构建完整文件路径
            String fullFilePath = uploadPath + filePath.replace("/uploads", "");
            File encryptedFile = new File(fullFilePath);
            
            if (!encryptedFile.exists()) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
            
            // 设置响应头
            response.setContentType("audio/mpeg");
            response.setHeader("Content-Disposition", "inline; filename=\"" + encryptedFile.getName() + "\"");
            
            // 生成密钥并解密文件
            SecretKey secretKey = AESUtil.loadKey(audioEncryptionKey);
            
            // 创建临时解密文件
            File tempDecryptedFile = File.createTempFile("decrypted_", ".tmp");
            tempDecryptedFile.deleteOnExit();
            
            // 解密文件
            AESUtil.decryptFile(encryptedFile, tempDecryptedFile, secretKey);
            
            // 将解密后的文件内容写入响应
            try (FileInputStream fis = new FileInputStream(tempDecryptedFile);
                 OutputStream os = response.getOutputStream()) {
                
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = fis.read(buffer)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
                os.flush();
            }
            
            // 删除临时文件
            tempDecryptedFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}